package com.sk.bilibili.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sk.bilibili.event.BiliBiliEvent;
import com.sk.bilibili.other.R;
import com.sk.bilibili.property.MinioProperty;
import com.sk.bilibili.utils.QueryWrapperUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import com.sk.bilibili.bean.Video;
import com.sk.bilibili.mapper.VideoMapper;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author 邵康
 * @date 2021/11/23 16:10
 */
@Service
public class VideoService extends ServiceImpl<VideoMapper, Video> {

    @Autowired
    private MinioService minioService;
    @Autowired
    private MinioProperty minioProperty;
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    private static final String URL_PATH = "video/url/%s";
    private static final Pattern URL_PATTERN = Pattern.compile("/(video/url/.*)$");
    private static final Pattern NAME_PATTERN = Pattern.compile("video/url/(.*)\\..+$");
    private static final String COVER_PATH = "%svideo/cover/%s-%d.jpg";

    public R<List<String>> add(Video video) {
        video.setUrl(minioService.add(video.getUrlFile(), getPath(video.getUrlFile())));
        checkTitle(video);
        save(video);
        List<String> covers = generateCover(video.getUrl());
        eventPublisher.publishEvent(new BiliBiliEvent<>(this,video));
        return R.success(covers);
    }

    private String getPath(MultipartFile file) {
        if(file==null)return null;
        String filename = file.getOriginalFilename();
        return URL_PATH+filename.substring(filename.lastIndexOf('.'));
    }

    private List<String> generateCover(String url) {
        Matcher matcher = NAME_PATTERN.matcher(url);
        List<String> res = new ArrayList<>();
        if (matcher.find()) {
            String name = matcher.group(1);
            String basePath = minioProperty.getBasePath();
            for (int i = 0; i < 3; i++) {
                res.add(String.format(COVER_PATH, basePath, name, i));
            }
        }
        return res;
    }

    private void checkTitle(Video video) {
        if (video.getTitle() != null) return;
        video.setTitle(video.getUrlFile().getOriginalFilename());
    }

    public R<Void> delete(Integer id) {
        Video temp = getById(id);
        minioService.delete(temp.getUrl(), URL_PATTERN);
        removeById(id);
        return R.success();
    }

    public R<Void> update(Video video) {
        Video temp = getById(video.getId());
        String url = minioService.update(getPath(video.getUrlFile()), URL_PATTERN, temp.getUrl(), video.getUrlFile());
        video.setUrl(url);
        updateById(video);
        return R.success();
    }

    public R<IPage<Video>> page(Integer page, Integer size) {
        return R.success(page(new Page<>(page, size), null));
    }

    public R<Video> getVideo(Integer id) {
        return R.success(getById(id));
    }

    public List<Video> getVideos(Integer videoSetId) {
        QueryWrapper<Video> queryWrapper = QueryWrapperUtils.eq("video_set_id", videoSetId);
        return list(queryWrapper);
    }

    public Integer getNum(Integer videoSetId) {
        QueryWrapper<Video> queryWrapper = QueryWrapperUtils.eq("video_set_id", videoSetId);
        return count(queryWrapper);
    }

    public Video getLatestVideo(Integer videoSetId) {
        return baseMapper.getLatestVideo(videoSetId);
    }

}
